package com.algo.util;

import org.springframework.cglib.beans.BeanCopier;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * bean拷贝工具类
 */
public class BeanCopyUtils {

    /**
     * BeanCopier缓存，享元思想
     */
    private static volatile Map<String, BeanCopier> cacheMap = new HashMap<>();

    /**
     * 属性拷贝
     * @param source 元数据
     * @param target 目标
     */
    public static <T, S> void copyProperties(S source, T target) {
        getBeanCopier(source, target).copy(source, target, null);
    }

    /**
     * 获取 BeanCopier
     * @param source 元数据
     * @param target 目标数据
     * @return BeanCopier
     */
    private static BeanCopier getBeanCopier(Object source, Object target) {
        String cacheKey = getCacheKey(source, target);
        BeanCopier beanCopier = cacheMap.get(cacheKey);
        if (beanCopier == null) {
            synchronized (cacheMap) {
                if ((beanCopier = cacheMap.get(cacheKey)) == null) {
                    beanCopier = BeanCopier.create(source.getClass(), target.getClass(), false);
                    cacheMap.put(cacheKey, beanCopier);
                }
            }
        }
        return beanCopier;
    }

    /**
     * 生成缓存 key
     * @param source 元数据
     * @param target 目标类
     * @return 缓存key
     */
    private static String getCacheKey(Object source, Object target) {
        return source.getClass().getSimpleName() + "_" + target.getClass().getSimpleName();
    }
}
